package controller

import (
	"bg/libs"
	"encoding/json"
	"fmt"
	"github.com/garyburd/redigo/redis"
	"html/template"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"strconv"
	"strings"
	"time"
)

type insertClass struct {
	user_id     int
	user_name   string
	user_pwd    string
	user_avator string
}

//首页
func Index(w http.ResponseWriter, r *http.Request) {
	if r.RequestURI == "/favicon.ico" {
		return
	}
	defer func() {
		if err := recover(); err != nil {
			fmt.Fprint(w, err)
		}
	}()
	file := libs.GetSourcePath()
	tpl, err := template.ParseFiles(file + "/html/index.html")
	if err != nil {
		panic(err)
	}
	tpl.Execute(w, nil)
}

//登陆页面
func LoginPage(w http.ResponseWriter, r *http.Request) {
	defer func() {
		if err := recover(); err != nil {
			fmt.Fprint(w, err)
		}
	}()
	file := libs.GetSourcePath()
	tpl, err := template.ParseFiles(file + "/html/login.html")
	if err != nil {
		panic(err)
	}
	tpl.Execute(w, nil)
}

//登陆方法
func Login(w http.ResponseWriter, r *http.Request) {
	defer func() {
		if err := recover(); err != nil {
			returnParam := map[string]interface{}{
				"code": "400",
				"msg":  fmt.Sprint(err),
			}
			jj, err := json.Marshal(returnParam)
			if err != nil {
				fmt.Println(err)
			}
			fmt.Fprintf(w, string(jj))
		}

	}()
	type param struct {
		name string
		pwd  string
	}
	var params param
	if err := r.ParseForm(); err != nil {
		panic(err)
	}
	if value, res := r.PostForm["name"]; res && value[0] != "" {
		params.name = value[0]
	} else {
		panic("请输入账号")
	}
	if value, res := r.PostForm["pwd"]; res && value[0] != "" {
		params.pwd = value[0]
	} else {
		panic("请输入密码")
	}
	sql := "select * from go_user where user_name=? and user_pwd=?"
	// sql := fmt.Sprintf(, params.name, params.pwd)
	res := libs.QueryDb(sql, params.name, params.pwd)
	if len(res) <= 0 {
		panic("账号密码错误")
	}
	if len(res) > 0 {
		//更新登陆时间
		sql := "update go_user set create_time=? where user_name=? and user_pwd=?"
		libs.ExcuteDb(sql, time.Now().Unix(), params.name, params.pwd)
	}
	//生成缓存用户信息
	CacheUser(res[0])

	returnParam := map[string]interface{}{
		"code": "200",
		"msg":  "success",
		"data": res[0],
	}
	bytes, _ := json.Marshal(returnParam)
	fmt.Fprint(w, string(bytes))
}

/*
* 注册页面
 */
func RegistePage(w http.ResponseWriter, r *http.Request) {
	defer func() {
		if err := recover(); err != nil {
			fmt.Fprint(w, err)
		}
	}()
	file := libs.GetSourcePath()
	tpl, err := template.ParseFiles(file + "/html/register.html")
	if err != nil {
		panic(err)
	}
	tpl.Execute(w, nil)
}

/*
 * 注册接口
 */

func Register(w http.ResponseWriter, r *http.Request) {
	defer func() {
		if err := recover(); err != nil {
			fmt.Print(err)
			bytes, _ := json.Marshal(map[string]interface{}{
				"code": 400,
				"msg":  err,
				"data": "",
			})
			fmt.Fprint(w, string(bytes))
		}
	}()
	var insertData insertClass
	upload, handle, err := r.FormFile("avator")
	data := r.PostForm
	//验证
	if data["user"][0] == "" || data["pwd"][0] == "" {
		panic("请输入账号或者密码")
	}
	insertData.user_name = data["user"][0]
	insertData.user_pwd = data["pwd"][0]
	sql := "select * from go_user where user_name=?"
	list := libs.QueryDb(sql, data["user"][0])
	if len(list) > 0 {
		panic("该账号已被注册")
	}
	if err == nil {
		//中文字符截取方法
		rs := []rune(handle.Filename)
		suffix := string(rs[strings.LastIndex(handle.Filename, "."):])

		insertData.user_avator = strconv.FormatInt(time.Now().Unix(), 10) + "_" + data["user"][0] + suffix
		defer upload.Close()
		file := libs.GetSourcePath()
		newfile, err := os.OpenFile(file+"/img/"+insertData.user_avator, os.O_WRONLY|os.O_CREATE, 0755)
		if err != nil {
			panic("文件打开错误")
		}
		defer newfile.Close()
		if _, err := io.Copy(newfile, upload); err != nil {
			defer panic("文件上传失敗")
		}
	}
	insertSql := "insert into go_user(user_name,user_pwd,user_avator) values(?,?,?)"
	res, _ := libs.ExcuteDb(insertSql, insertData.user_name, insertData.user_pwd, insertData.user_avator)
	if res <= 0 {
		panic("注册失败!")
	}
	//设置缓存

	cache := CacheUser(map[string]string{
		"user_name":   insertData.user_name,
		"user_pwd":    insertData.user_pwd,
		"user_avator": insertData.user_avator,
	})
	b, _ := json.Marshal(map[string]interface{}{
		"code": 200,
		"msg":  "注册成功",
		"data": map[string]string{
			"token": cache,
		},
	})
	w.Write(b)

}

//编辑个人信息
func EditUser(w http.ResponseWriter, r *http.Request) {
	defer func() {
		if err := recover(); err != nil {
			bytes, _ := json.Marshal(map[string]interface{}{
				"code": 400,
				"msg":  err,
			})
			w.Write(bytes)
		}
	}()
	file, fileHeader, err := r.FormFile("avator")
	//参数列表
	user_id := r.PostForm["user_id"][0]
	user := r.PostForm["user"][0]
	pwd := r.PostForm["pwd"][0]

	user_avator := ""
	if user_id == "" {
		panic("用户id不能为空")
	}
	if user == "" {
		panic("用户名不能为空")
	}
	if pwd == "" {
		panic("用户密码不能为空")
	}
	if err == nil {
		defer file.Close()
		//上传文件
		rs := []rune(fileHeader.Filename)
		suffix := string(rs[strings.LastIndex(fileHeader.Filename, "."):])
		user_avator = strconv.FormatInt(time.Now().Unix(), 10) + "_" + user + suffix
		Sourcefile := libs.GetSourcePath()
		newFile, err := os.Create(Sourcefile + "/img/" + user_avator)
		defer newFile.Close()
		if err != nil {
			panic("文件打开失败")
		}
		if _, err := io.Copy(newFile, file); err != nil {
			panic("文件上传失败")
		}
	}
	//校验重名
	var sql string = ""
	sql = "select count(*) as num from go_user where user_id != ? and user_name = ?"
	res := libs.QueryRowDb(sql, user_id, user)
	if num, _ := strconv.Atoi(res["num"]); num > 0 {
		panic("用户名已经存在!")
	}
	r1 := int64(0)
	r2 := int64(0)
	fmt.Println(r1, r2, user_avator)
	if user_avator != "" {
		sql = "update go_user set user_name=?,user_pwd=?,user_avator=? where user_id=?"
		r1, r2 = libs.ExcuteDb(sql, user, pwd, user_avator, user_id)
		fmt.Println(r1, r2)
	} else {
		sql = "update go_user set user_name=?,user_pwd=? where user_id=?"
		r1, r2 = libs.ExcuteDb(sql, user, pwd, user_id)
		fmt.Println(r1, r2)
	}
	fmt.Println(r1, r2)
	if r1 == 0 && r2 == 0 {
		panic("修改失败!")
	}
	//修改缓存的用户信息
	conn, err := libs.RedisCon()
	if err != nil {
		panic(err)
	}
	conn.Close()

	bytes, _ := json.Marshal(map[string]interface{}{
		"code": 200,
		"msg":  "修改成功",
	})
	w.Write(bytes)
}

//获取用户登陆状态
func GetUserLogin(w http.ResponseWriter, r *http.Request) {
	defer func() {
		if err := recover(); err != nil {
			res := map[string]interface{}{
				"code": 400,
				"msg":  err,
			}
			bytes, _ := json.Marshal(res)
			w.Write(bytes)
		}
	}()
	r.ParseForm()
	token := r.PostFormValue("token")
	if token == "" {
		token = r.FormValue("token")
	}
	conn, err := libs.RedisCon()
	if err != nil {
		panic("连接失败")
	}
	defer conn.Close()
	userInfoJson, err := redis.String(conn.Do("get", token))
	if err != nil {
		panic("未登录")
	}
	userInfo := make(map[string]string)

	if err := json.Unmarshal([]byte(userInfoJson), &userInfo); err != nil {
		panic(err)
	}
	Result := map[string]interface{}{
		"code": 200,
		"msg":  "success",
		"data": userInfo,
	}
	bytes, err := json.Marshal(Result)
	w.Write(bytes)

}

//退出登陆
func Logout(w http.ResponseWriter, r *http.Request) {
	defer func() {
		if err := recover(); err != nil {
			res := map[string]interface{}{
				"code": 400,
				"msg":  err,
			}
			bytes, _ := json.Marshal(res)
			w.Write(bytes)
		}
	}()
	conn, err := libs.RedisCon()
	if err != nil {
		panic("redis连接失败")
	}
	token := r.PostFormValue("token")
	if _, err := redis.Bool(conn.Do("del", token)); err != nil {
		panic("退出失败")
	}
	bytes, _ := json.Marshal(map[string]interface{}{
		"code": 200,
		"msg":  "退出成功",
	})
	w.Write(bytes)
}
func CacheUser(res map[string]string) string {
	//生成md5
	md5crypt := libs.MD5(res["user_name"] + string(time.Now().Unix()))
	res["token"] = md5crypt
	cacheValue, _ := json.Marshal(res)

	//redis存储key
	conn, err := libs.RedisCon()
	if err != nil {
		panic(err)
	}
	defer conn.Close()
	if _, seterr := redis.String(conn.Do("set", md5crypt, cacheValue, "ex", 60*60*2)); seterr != nil {
		panic(seterr)
	}
	return md5crypt
}
func goroutine(w http.ResponseWriter, r *http.Request) {

	defer func() {
		if err := recover(); err != nil {
			res := map[string]interface{}{
				"code": 400,
				"msg":  err,
			}
			bytes, _ := json.Marshal(res)
			w.Write(bytes)
		}
	}()

	start := time.Now().UnixNano() / 1000000
	// resp, err := http.Get("http://www.baidu.com/")
	// if err != nil {
	// 	fmt.Println(err)
	// }
	// defer resp.Body.Close()
	// body, err := ioutil.ReadAll(resp.Body)
	// if err != nil {
	// 	fmt.Println(err)
	// }
	// fmt.Println(string(body))
	// return

	channel := make(chan string)
	hote_id := make([]int, 0)
	hote_id = append(hote_id, 1512824)
	hote_id = append(hote_id, 1530072)
	hote_id = append(hote_id, 342124)
	hote_id = append(hote_id, 299792)
	hote_id = append(hote_id, 305012)
	hote_id = append(hote_id, 298467)
	hote_id = append(hote_id, 307529)
	hote_id = append(hote_id, 309166)
	hote_id = append(hote_id, 328443)
	hote_id = append(hote_id, 165723591)
	fmt.Println(hote_id)
	for _, i := range hote_id {
		go func(c chan string, i int) {
			// c <- time.Now().Format("2006-01-02 15:04:05")

			resp, err := http.Get("http://middle.com/hotel/meituan/getHotelGoodsRp/2/" + strconv.Itoa(i))
			if err != nil {
				fmt.Println(err)
			}
			defer resp.Body.Close()
			body, err1 := ioutil.ReadAll(resp.Body)
			if err1 != nil {
				fmt.Println(err)
			}
			// fmt.Println(string(body))
			channel <- string(body)
			// fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
		}(channel, i)
	}
	res := make([]string, 0)
	for range hote_id {
		jsonStr := <-channel
		res = append(res, jsonStr)
	}
	// for v := range channel {
	// 	fmt.Println(v) //循环取出通道里面的值,先进先出
	// }
	end := time.Now().UnixNano() / 1000000
	for _, v := range res {
		w.Write([]byte("\n\n\n\n"))
		w.Write([]byte(v))
	}
	fmt.Println(end - start)

}

func Test(w http.ResponseWriter, r *http.Request) {
	//var c chan int
	c := make(chan int, 10)

	for i := 0; i < 10; i++ {
		go func(c chan int, i int) {
			c <- i
		}(c, i)
	}
	for i := 0; i < 10; i++ {
		fmt.Println(<-c)
	}
	//for v := range c {
	//	fmt.Println(<-v)
	//}
	close(c)
	fmt.Fprintf(w, "end")
}
func Testab(w http.ResponseWriter, r *http.Request) {
	//var name string = "gxk"
	//var psd string = "123456"
	sql := "select * from go_user where user_id=?"
	//sql := fmt.Sprintf(, params.name, params.pwd)
	type aaa []map[string]string
	var c chan aaa
	c = make(chan aaa)
	for i := 0; i < 100; i++ {
		go func(c chan aaa) {
			res := libs.QueryDb(sql, 1)
			c <- res
		}(c)
	}
	result := make(aaa, 0)
	for i := 0; i < 100; i++ {
		//res := <-c
		//fmt.Println(reflect.TypeOf(res))
		//for v := range res {
		//	fmt.Println("%+v", v)
		//}
		result = append(result, <-c...)
		//fmt.Println("%+v", res[0])
	}
	fmt.Println("%+v", result)
	bytes, _ := json.Marshal(result)
	fmt.Fprintf(w, string(bytes))
}

func T1(w http.ResponseWriter, r *http.Request) {
}
func T2(w http.ResponseWriter, r *http.Request) {
	fmt.Println("bbb")
}
